package antistatic.spinnerwheel;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.animation.Interpolator;
import android.widget.Scroller;

import com.baidu.location.BDLocation;
import com.lidroid.xutils.bitmap.BitmapGlobalConfig.BitmapCacheManagementTask;

public class WheelScroller {
	public static final int MIN_DELTA_FOR_SCROLLING = 1;
	private static final int SCROLLING_DURATION = 400;
	private final int MESSAGE_JUSTIFY;
	private final int MESSAGE_SCROLL;
	private Handler animationHandler;
	private Context context;
	private GestureDetector gestureDetector;
	private SimpleOnGestureListener gestureListener;
	private boolean isScrollingPerformed;
	private int lastScrollY;
	private float lastTouchedY;
	private ScrollingListener listener;
	private Scroller scroller;

	public static interface ScrollingListener {
		void onFinished();

		void onJustify();

		void onScroll(int i);

		void onStarted();
	}

	public WheelScroller(Context context, ScrollingListener listener) {
		this.gestureListener = new SimpleOnGestureListener() {
			@Override
			public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
				return true;
			}

			@Override
			public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
				WheelScroller.this.lastScrollY = 0;
				WheelScroller.this.scroller.fling(0, WheelScroller.this.lastScrollY, 0, (int) (-velocityY), 0, 0,
						-2147483647, Integer.MAX_VALUE);
				WheelScroller.this.setNextMessage(0);
				return true;
			}
		};
		this.MESSAGE_SCROLL = 0;
		this.MESSAGE_JUSTIFY = 1;
		this.animationHandler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				WheelScroller.this.scroller.computeScrollOffset();
				int currY = WheelScroller.this.scroller.getCurrY();
				int delta = WheelScroller.this.lastScrollY - currY;
				WheelScroller.this.lastScrollY = currY;
				if (delta != 0) {
					WheelScroller.this.listener.onScroll(delta);
				}
				if (Math.abs(currY - WheelScroller.this.scroller.getFinalY()) < 1) {
					currY = WheelScroller.this.scroller.getFinalY();
					WheelScroller.this.scroller.forceFinished(true);
				}
				if (!WheelScroller.this.scroller.isFinished()) {
					WheelScroller.this.animationHandler.sendEmptyMessage(msg.what);
				} else if (msg.what == 0) {
					WheelScroller.this.justify();
				} else {
					WheelScroller.this.finishScrolling();
				}
			}
		};
		this.gestureDetector = new GestureDetector(context, this.gestureListener);
		this.gestureDetector.setIsLongpressEnabled(false);
		this.scroller = new Scroller(context);
		this.listener = listener;
		this.context = context;
	}

	public void setInterpolator(Interpolator interpolator) {
		this.scroller.forceFinished(true);
		this.scroller = new Scroller(this.context, interpolator);
	}

	public void scroll(int distance, int time) {
		this.scroller.forceFinished(true);
		this.lastScrollY = 0;
		this.scroller.startScroll(0, 0, 0, distance, time != 0 ? time : SCROLLING_DURATION);
		setNextMessage(0);
		startScrolling();
	}

	public void stopScrolling() {
		this.scroller.forceFinished(true);
	}

	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case BDLocation.TypeNone /* 0 */:
			this.lastTouchedY = event.getY();
			this.scroller.forceFinished(true);
			clearMessages();
			break;
		case BitmapCacheManagementTask.MESSAGE_FLUSH /* 2 */:
			int distanceY = (int) (event.getY() - this.lastTouchedY);
			if (distanceY != 0) {
				startScrolling();
				this.listener.onScroll(distanceY);
				this.lastTouchedY = event.getY();
				break;
			}
			break;
		}
		if (!this.gestureDetector.onTouchEvent(event) && event.getAction() == 1) {
			justify();
		}
		return true;
	}

	private void setNextMessage(int message) {
		clearMessages();
		this.animationHandler.sendEmptyMessage(message);
	}

	private void clearMessages() {
		this.animationHandler.removeMessages(0);
		this.animationHandler.removeMessages(MIN_DELTA_FOR_SCROLLING);
	}

	private void justify() {
		this.listener.onJustify();
		setNextMessage(MIN_DELTA_FOR_SCROLLING);
	}

	private void startScrolling() {
		if (!this.isScrollingPerformed) {
			this.isScrollingPerformed = true;
			this.listener.onStarted();
		}
	}

	void finishScrolling() {
		if (this.isScrollingPerformed) {
			this.listener.onFinished();
			this.isScrollingPerformed = false;
		}
	}
}